package com.zwp.base.base

import android.app.Dialog
import android.content.Intent
import android.os.Bundle
import androidx.activity.result.ActivityResult
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.databinding.DataBindingUtil
import androidx.databinding.ViewDataBinding
import androidx.fragment.app.DialogFragment
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.ViewTreeLifecycleOwner
import com.zwp.base.BR
import com.zwp.base.R
import com.zwp.base.state.*
import com.zwp.base.uitls.CustomDensity
import com.zwp.base.widget.LoadingDialogFragment
import java.lang.reflect.ParameterizedType

abstract class BaseActivity<VM : BaseViewModel, BD : ViewDataBinding> : AppCompatActivity() {

    val viewModel by lazy {
        ViewModelProvider(this).get(getTypeClass())
    }

    val activityForResult by lazy {
        registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
            parserResult(it)
        }
    }

    lateinit var binding: BD

    private var dialog: Dialog? = null

    private var dialogFragment: DialogFragment? = null



    override fun onCreate(savedInstanceState: Bundle?) {
        //databinding绑定view操作的flow需要用到
        ViewTreeLifecycleOwner.set(window.decorView, this)
        //屏幕适配
        CustomDensity(this, application, 375)
        super.onCreate(savedInstanceState)

        binding = DataBindingUtil.setContentView(this, getLayoutResId())

        binding.setVariable(BR.viewModel, viewModel)

        initViewDataBinding()
        //页面数据初始化方法
        initData()
        //页面事件监听的方法，一般用于ViewModel层转到View层的事件注册
        initObservale()
        registerUiChangeLiveDataCallBack()
    }

    override fun onDestroy() {
        super.onDestroy()
        binding.unbind()
    }

    open fun parserResult(activityResult: ActivityResult) {}

    open fun initData() {}

    open fun initObservale() {}

    abstract fun getLayoutResId(): Int

    protected fun needDefaultView() = true

    protected fun registerUiChangeLiveDataCallBack() {
        viewModel.let {
            it.uc.finishEvent.observe(this) { finish() }
            it.uc.onBackPressedEvent.observe(this) { onBackPressed() }
            it.uc.startActivityEvent.observe(this) {
                val clz = it[BaseViewModel.ParameterField.CLASS] as Class<*>
                val bundle = it[BaseViewModel.ParameterField.BUNDLE] as? Bundle
                activityForResult.launch(Intent(this, clz).apply {
                    if (bundle != null) {
                        putExtras(bundle)
                    }
                })
            }
            it.uc.showDialogEvent.observe(this) {
                showLoadingDialog()
            }
            it.uc.dismissDialogEvent.observe(this) {
                dismissDialog()
            }
        }
    }

    fun initViewDataBinding() {

        if (needDefaultView()) {
            StateModelController(
                this,
                this,
                useCustomLayout(),
                viewModel.stateModel,
                createStateContainerProcessor()
            )
        }
    }

    /**
     * 缺省页的layout
     */
    protected fun useCustomLayout() = R.layout.base_activity_default


    /**
     * 构建缺省页容器
     */
    fun createStateContainerProcessor(): IStateContainerProcessor {
        val rootView = binding.root
        require(rootView is ConstraintLayout) { "根布局必须为ViewGroup才能添加缺省页" }
        return DefaultStateContainerProcessor(rootView)
    }


    fun showLoadingDialog(content: String = "加载中...") {
        if (dialogFragment == null) {
            dialogFragment = LoadingDialogFragment().apply {
                message = content
                show(supportFragmentManager)
            }
        }
    }

    fun dismissDialog() {
        if (dialogFragment != null && dialogFragment!!.isVisible) {
            dialogFragment!!.dismiss()
        }
    }

    fun getTypeClass() =
        javaClass.genericSuperclass!!.let {
            if (it is ParameterizedType) {
                it.actualTypeArguments[0] as Class<VM>
            } else {
                BaseViewModel::class.java as Class<VM>
            }
        }


}